﻿<!DOCTYPE html>


<html>


<head>
	<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

	<link rel="shortcut icon" type="image/png" href="assets/logo/logo.png"/>
	<link rel="stylesheet" href="docs/styles.css">

	<script>

const TEXTURES = [
	'Camouflage', 'Cave art', 'Circles', 'Clouds', 'Concrete', 'Cork',
	'Dalmatian spots', 'Dyson sphere', 'Entangled', 'Fordite', 'Gas giant',
	'Grid', 'Isolines', 'Karst rock', 'Marble', 'Neon lights', 'Planet',
	'Photosphere', 'Polka dots', 'Processed wood', 'Protozoa', 'Runny eggs',
	'Satin', 'Rough clay', 'Rust', 'Scepter head', 'Scream', 'Simplex noise',
	'Stars', 'Tiger fur', 'Voronoi cells', 'Water drops', 'Watermelon',
	'Wood', 'Zebra lines', 'Darth Maul', 'Brain', 'Static noise', 'Circle decor',
	'Reticular veins', 'Roman paving', 'Crumpled fabric', 'Isolayers',
	'Turbulent smoke', 'Caustics',
	//'aaa'
].sort();


const SHAPES = [
	'Rotator', 'Scaler', 'Translator', 'Supersphere',
].sort();


const EXAMPLES = [
	'Planet', 'Normal map', 'Wooden toys', 'Protozoa', 'Neck massage',
	'Watermelon', 'Texture in motion', 'Matrixed data'
].sort();


const VIDEOS = [
	{ title: 'Dancing Lee', xId: '1829064887701577986', info: 'Flexible skin without<br>skeleton, morphing or skinning' },
	{ title: 'Wooden Toys', xId: '1813922290813509737', info: 'Using TSL textures<br>on models with no UV coordinates' },
	{ title: 'Protozoa', xId: '1821507097164427685', info: 'The first in the world<br>ultrashort Sci-Fi horror movie' },
	{ title: 'Texture in motion', xId: '1874560640200921418', info: 'Dynamic blending<br>of TSL textures on an animated model' },
].sort();

const X_PREFIX = 'https://x.com/PavelBoytchev/status/';

	</script>
</head>


<body style="max-width: 60em;">
	<img class="logo" src="assets/logo/logo.png">
	<h1>TSL Textures</h1>


	<h3>Welcome. Pick a texture!</h3>
	<br>
	<br>

	<!-- list of textures, generated by a script -->
	<div id="textures" class="gallery">	</div>
	
	<br>
	<br>

	<h3>Shape textures</h3>
	<p style="max-width: 36em; margin: 1em auto;">
		Shape textures affect the shape of a 3D model, not its colors. They run
		in real-time just like the traditional textures. However, they require a sufficiently
		dense net of vertices.
	</p>
	<br>
	<br>

	<!-- list of textures, generated by a script -->
	<div id="shapes" class="gallery"></div>


	<p style="max-width: 36em; margin: 1em auto;">
		This project provides Three.js Shading Language (TSL) textures.
		TSL textures are functions that generate textures at run-time on the GPU.
		<a href="https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language">Learn more</a>
		about TSL and what makes it special. Contributions to this project are very welcome
		&ndash; either as new TSL textures or optimizations of existing ones.
		
		
		The texture functions are available
		on <a href="https://github.com/boytchev/tsl-textures">GitHub</a>
		and <a href="https://www.npmjs.com/package/tsl-textures">NPM</a>. You
		may see them in action here:
	</p>
	

	<h3>Examples</h3>

	<p style="max-width: 36em; margin: 1em auto;">
		A few examples demonstrating the use of TSL and TSL Textures. Some of
		the examples are prototypes and proof-of-concepts, others have been
		used to make short videos.
	</p>
	
	<!-- list of examples of TSL Textures, generated by a script -->
	<div id="examples" class="gallery"> </div>
	
	
	

	<h3>Short videos</h3>

	<p style="max-width: 36em; margin: 1em auto;">
		A small collection of videos based on TSL Texture examples. The videos
		are posted on X. Click on an image to view it on X or use the link to
		run the code live.
	</p>


	<!-- list of short videos, generated by a script -->
	<div id="videos" class="gallery"> </div>


	<div class="footnote">
		<a href="docs/cookies.html">Cookies</a> &middot; 
		<a href="docs/licence.html">Licence</a> <!--&middot; 
		<a href="docs/faq.html">FAQ</a>-->
	</div>


	<script>

function textureBlock( name ) {

	var file = name.toLowerCase().replaceAll( ' ', '-' );

	var html = '';

	html += '<a class="style-block" href="./online/'+file+'.html">';
	html += '    <div class="title">'+name+'</div>';
	html += '    <img src="./docs/images/'+file+'.png">';
	html += '</a>';

	return html;

}


function exampleBlock( name ) {

	var file = name.toLowerCase().replaceAll( ' ', '-' );

	var html = '';

	html += '<a class="style-block big-block" href="./examples/'+file+'/index.html">';
	html += '    <div class="title">'+name+'</div>';
	html += '    <img src="./examples/'+file+'/screenshot.jpg">';
	html += '</a>';

	return html;

}


function videoBlock( video ) {

	var file = video.title.toLowerCase().replaceAll( ' ', '-' );

	var html = '';
	html += '<a class="style-block video-block" href="'+X_PREFIX+video.xId+'">';
	html += '<div class="info">'+video.info+':</div>';
	html += '<img src="./media/'+file+'/screenshot.jpg">';
	html += '</a>';
	html += '<a class="live-right" href="./media/'+file+'/index.html">Live demo</span>';

	return html;

}


// creates a section of blocks
function section( id, names, block ) {

	var html = '';

	for ( var name of names ) html += block( name );

	document.getElementById( id ).innerHTML += html;

}


section( 'textures', TEXTURES, textureBlock );
section( 'shapes', SHAPES, textureBlock );
section( 'examples', EXAMPLES, exampleBlock );
section( 'videos', VIDEOS, videoBlock );


	</script>
	
</body>
</html>